﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
using System.Net.Sockets;
using Fcdbas.Core.Net;
using FileTransferProtocol;
using Fcdbas.Core.Util;
using Fcdbas.Core.Xml;
namespace FileTransferSrv
{
   
    class FileTransferServer : BaseSocketService
    {
        private FileSystemWatcher watcher = new FileSystemWatcher();
        private string SavePath;
        private string SaveTempPath;
        private string DownLoadPath;
        public event EventHandler FileListChanged;
        private OnEventMessageDelegate FOnEventDelegate;
        private List<TransferHead> TSendHeadList;
        private List<TransferHead> TDownLoadHeadList;
        private List<TFileInfo> DownLoadList;
        public List<TFileInfo> GetDownLoadList()
        {
            return DownLoadList;
        }
        private Dictionary<long, NetSession> DownLoadSessions = new Dictionary<long, NetSession>();
        //private Dictionary<long, bool> ConnectStatus = new Dictionary<long, bool>();
        private object LockHead;
        private string FileSendConfigPath;
        private string FileDownLoadConfigPath;
        private object LockDLList;
        //private Dictionary<long, ReceiveSync> RecSyncs = new Dictionary<long, ReceiveSync>();
        public FileTransferServer(OnEventMessageDelegate eventDelegate, string savePath, string download, bool IsEnableRaising = true)
        {
            DownLoadPath = download;
            FileSendConfigPath = AppDomain.CurrentDomain.BaseDirectory + "FileSendConfig.xml";
            FileDownLoadConfigPath = AppDomain.CurrentDomain.BaseDirectory + "FileDownLoadConfig.xml";
            LoadTranferFile();
            if(TSendHeadList == null)
                TSendHeadList = new List<TransferHead>();
            if (TDownLoadHeadList == null)
                TDownLoadHeadList = new List<TransferHead>();
            this.FOnEventDelegate = eventDelegate;
            SavePath = savePath;
            
            if (!Directory.Exists(SavePath))
            {
                Directory.CreateDirectory(SavePath);
            }
            SaveTempPath = SavePath + "\\Temp";
            if (!Directory.Exists(SaveTempPath))
            {
                Directory.CreateDirectory(SaveTempPath);
            }
            LockHead = new object();
            LockDLList = new object();
            DownLoadList = new List<TFileInfo>();
            WatcherStrat(DownLoadPath, "*.*", true, true);
            FindFile(DownLoadList, DownLoadPath);
        }
        public void SetWatcherEnable(bool enable)
        {
            watcher.EnableRaisingEvents = enable;
        }
        protected virtual void OnFileListChanged()
        {
            if (this.FileListChanged != null)
                FileListChanged.Invoke(this,EventArgs.Empty);
        }
        /// <summary>        
        /// 初始化监听        
        /// </summary>        
        /// <param name="StrWarcherPath">需要监听的目录</param>        
        /// <param name="FilterType">需要监听的文件类型(筛选器字符串)</param>        
        /// <param name="IsEnableRaising">是否启用监听</param>        
        /// <param name="IsInclude">是否监听子目录</param>         
        private  void WatcherStrat(string StrWarcherPath, string FilterType, bool IsEnableRaising, bool IsInclude)
        {
            //初始化监听            
            watcher.BeginInit();
            //设置监听文件类型            
            watcher.Filter = FilterType;
            //设置是否监听子目录            
            watcher.IncludeSubdirectories = IsInclude;
            //设置是否启用监听?            
            watcher.EnableRaisingEvents = IsEnableRaising;
            //设置需要监听的更改类型(如:文件或者文件夹的属性,文件或者文件夹的创建时间;NotifyFilters枚举的内容)           
            watcher.NotifyFilter = NotifyFilters.Attributes | NotifyFilters.CreationTime | NotifyFilters.DirectoryName | NotifyFilters.FileName | NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.Security | NotifyFilters.Size;
            //设置监听的路径            
            watcher.Path = StrWarcherPath;
            //注册创建文件或目录时的监听事件            
            watcher.Created += new FileSystemEventHandler(watch_created);
            //注册当指定目录的文件或者目录发生改变的时候的监听事件   
            watcher.Changed += new FileSystemEventHandler(watch_changed);
            //注册当删除目录的文件或者目录的时候的监听事件            
            watcher.Deleted += new FileSystemEventHandler(watch_deleted);
            //当指定目录的文件或者目录发生重命名的时候的监听事件            
            watcher.Renamed += new RenamedEventHandler(watch_renamed);
            //结束初始化            
            watcher.EndInit();
        }
        /// <summary>        
        /// 创建文件或者目录时的监听事件       
        /// </summary>       
        /// <param name="sender"></param>        
        /// <param name="e"></param>        
        private  void watch_created(object sender, FileSystemEventArgs e)
        {
            //事件内容
            DownLoadListUpdate(e);

        }
        private void DownLoadListUpdate(FileSystemEventArgs e)
        {
            if (e.ChangeType != WatcherChangeTypes.Deleted && Fcdbas.Core.Util.FileHelper.IsDir(e.FullPath))
                return;
            TFileInfo fi = DownLoadList.Find(p => p.File == e.FullPath);
            if (fi != null)
            {
                lock (LockDLList)
                {
                    DownLoadList.Remove(fi);
                }
                OnFileListChanged();
            }
            if (e.ChangeType == WatcherChangeTypes.Changed )
            {
                TFileInfo tfi = TFileInfo.GetFileInfo(e.FullPath);
                lock (LockDLList)
                {
                    DownLoadList.Add(tfi);
                }
                OnFileListChanged();
            }
            
        }
        /// <summary>        
        /// 当指定目录的文件或者目录发生改变的时候的监听事件       
        /// </summary>        
        /// <param name="sender"></param>        
        /// <param name="e"></param>        
        private  void watch_changed(object sender, FileSystemEventArgs e)
        {
            //事件内容     
            DownLoadListUpdate(e);
        }
        /// <summary>        
        /// 当删除目录的文件或者目录的时候的监听事件        
        /// </summary>        
        /// <param name="sender"></param>              
        /// <param name="e"></param>       
        private  void watch_deleted(object sender, FileSystemEventArgs e)
        {
            //事件内容 
            DownLoadListUpdate(e);
        }
        /// <summary>        
        /// 当指定目录的文件或者目录发生重命名的时候的事件       
        /// </summary>       
        /// <param name="sender"></param>        
        /// <param name="e"></param>        
        private void watch_renamed(object sender, RenamedEventArgs e)
        {
            //事件内容       

        }
        /// <summary>        
        /// 启动或者停止监听        
        /// </summary>        
        /// <param name="IsEnableRaising">True:启用监听,False:关闭监听</param>        
        private void WatchStartOrSopt(bool IsEnableRaising)
        {
            watcher.EnableRaisingEvents = IsEnableRaising;
        }      
        private void FindFile( List<string >FileList ,string filePath)
        {
            //在指定目录及子目录下查找文件,在listBox1中列出子目录及文件
            DirectoryInfo Dir=new DirectoryInfo(filePath);

            foreach(DirectoryInfo d in Dir.GetDirectories())//查找子目录 
            {
                FindFile(FileList, Dir+ "\\" + d.ToString());
            }
            foreach(FileInfo f in Dir.GetFiles()) //查找文件
            {
                FileList.Add(Dir+"\\" + f.ToString()); 
            }

        }
        private void FindFile(List<TFileInfo> FileList, string filePath)
        {
            //在指定目录及子目录下查找文件,在listBox1中列出子目录及文件
            DirectoryInfo Dir = new DirectoryInfo(filePath);

            foreach (DirectoryInfo d in Dir.GetDirectories())//查找子目录 
            {
                FindFile(FileList, Dir + "\\" + d.ToString());
            }
            foreach (FileInfo f in Dir.GetFiles()) //查找文件
            {
                TFileInfo fi = TFileInfo.GetFileInfo(f.FullName);
                FileList.Add(fi);
            }

        }
        private void LoadTranferFile()
        {
            TSendHeadList = Fcdbas.Core.Xml.XmlHelper.ToXmlFileEntity<List<TransferHead>>(FileSendConfigPath);
            TDownLoadHeadList = Fcdbas.Core.Xml.XmlHelper.ToXmlFileEntity<List<TransferHead>>(FileDownLoadConfigPath);
        }
        private void Event(string eventMessage)
        {

            if (FOnEventDelegate != null)
            {
                FOnEventDelegate(eventMessage);
            }

        }
        public void SaveTranferFile()
        {
            for (int i = 0; i < TSendHeadList.Count; i++)
            {
                for (int j = 0; j < TSendHeadList[i].Blocks.Count; j++)
                {
                    TSendHeadList[i].Blocks[j].Data = null;
                    if (TSendHeadList[i].Blocks[j].FStream != null)
                    {
                        TSendHeadList[i].Blocks[j].FStream.Flush();
                        TSendHeadList[i].Blocks[j].FStream.Close();
                        TSendHeadList[i].Blocks[j].FStream = null;
                    }
                }
            }
          
            Fcdbas.Core.Xml.XmlHelper.ToXmlFile(TSendHeadList, FileSendConfigPath);

            //for (int i = 0; i < TDownLoadHeadList.Count; i++)
            //{
            //    for (int j = 0; j < TDownLoadHeadList[i].Blocks.Count; j++)
            //    {
            //        TDownLoadHeadList[i].Blocks[j].Data = null;
                    
            //    }
            //}

            //Fcdbas.Core.Xml.XmlHelper.ToXmlFile(TDownLoadHeadList, FileDownLoadConfigPath);
        }
        private TransferHead InitTransferHead(TransferHead tHead ,ref bool resume)
        {
            TransferHead th = TSendHeadList.Find(p => p.Guid == tHead.Guid);
            if (th != null)
            {
                resume = true;
                return th;
            }
            tHead.FileInfo.FilePath = SavePath + "\\" + tHead.Guid;
            if (!Directory.Exists(tHead.FileInfo.FilePath))
            {
                Directory.CreateDirectory(tHead.FileInfo.FilePath);
            }
            string tempath = SaveTempPath + "\\" + tHead.Guid;
            if (!Directory.Exists(tempath))
            {
                Directory.CreateDirectory(tempath);
            }
            for (int i = 0; i < tHead.Blocks.Count; i++)
            {
                FileBlock block = tHead.Blocks[i];
                block.TempFile = tempath + "\\" + block.TempFile;
            }
            
            TSendHeadList.Add(tHead);
            resume = false;
            return tHead;
        }
       
        private void WriteToTempFile(FileBlock block)
        {
            TransferHead head = TSendHeadList.Find(p => p.Guid == block.Guid);
            if (head == null)
                return;
            
            FileBlock fb = head.Blocks.Find(p => p.BlockId == block.BlockId);
            if (fb == null)
                return;
            if (fb.FStream == null)
            {
                fb.FStream = new FileStream(fb.TempFile, FileMode.Create, FileAccess.ReadWrite);		
            }
            //FileHelper.WriteBuffToFile(block.Data, (int)fb.HasTransfer,block.CurrentSize , fb.TempFile, "", false);
            fb.FStream.Position = fb.HasTransfer;
            fb.FStream.Write(block.Data, 0, block.CurrentSize);
            fb.FStream.Flush();
            lock (LockHead)
            {
                fb.HasTransfer = block.HasTransfer;
                fb.Complated = block.Complated;
            }
            if (fb.Complated)
            {
                
                fb.FStream.Close();
                fb.FStream = null;
            }
        }
        private bool bWriteToFile = false;
        private void WriteToFile(FileBlock block)
        {
            WriteToTempFile(block);
            Thread.Sleep(500);
            TransferHead head = TSendHeadList.Find(p => p.Guid == block.Guid);
            if (head == null)
                return;
            bool complated = true;
            foreach (FileBlock b in head.Blocks)
            {
                if (!b.Complated)
                {
                    complated = false;
                    break;
                }
            }
            if (!complated)
                return;
            while (bWriteToFile)
            {
                Thread.Sleep(100);
            }

            bWriteToFile = true;
            int ReadSize = 10240;
            var fbs = head.Blocks.OrderBy(p => p.BeginPos);
            int writeOffset = 0;
            FileStream fwrite = new FileStream(head.FileInfo.FilePath + "\\" + head.FileInfo.FileName , FileMode.Create, FileAccess.Write);
            ///合并文件
            foreach (FileBlock fb in fbs)
            {
                FileStream fs = new FileStream(fb.TempFile ,FileMode.Open ,FileAccess.ReadWrite) ;
                
                byte[] data = new byte[ReadSize];
                int readoffset = 0;
                int read = 0;
                read = fs.Read(data, 0, ReadSize);
                while (read > 0 && readoffset < fb.TotalSize)
                {
                    fwrite.Position = writeOffset;
                    fwrite.Write(data, 0, read);
                    readoffset += read;
                    writeOffset += read;
                    fs.Position = readoffset;
                    read = fs.Read(data, 0, ReadSize);
                }
                if (read > 0)
                {
                    fwrite.Write(data, 0, read);
                    writeOffset += read;
                }
                fs.Close();
            }
            fwrite.Flush();
            fwrite.Close();
            lock (LockHead)
            {
                TSendHeadList.Remove(head);
            }
            bWriteToFile = false;
        }
        private DateTime sendDt = DateTime.Now;
        private void ReadAndSend(ISocketConnection Connection, NetSession Session)
        {
            if (Session.FileBlock.Complated)
                return;
            if (Session.FileBlock.FStream == null)
                Session.FileBlock.FStream = new FileStream(Session.FileBlock.FileName, FileMode.Open, FileAccess.Read);
            FileStream fs = Session.FileBlock.FStream;
            //int nCount = 0;
          //  DateTime dt = DateTime.Now;
            byte[] read = new byte[ConstValue.SendSize];

            int readCount = 0;
            fs.Seek(Session.FileBlock.BeginPos + Session.FileBlock.HasTransfer, SeekOrigin.Begin);
            if (Session.FileBlock.TotalSize > Session.FileBlock.HasTransfer + ConstValue.SendSize)
            {
                Session.CmdType = FileTransferProtocol.CommandType.DownTransfer;
                readCount = fs.Read(read, 0, ConstValue.SendSize);
            }
            else
            {
                readCount = fs.Read(read, 0, (int)(Session.FileBlock.EndPos - Session.FileBlock.BeginPos - Session.FileBlock.HasTransfer) + 1);
                Session.FileBlock.Complated = true;
                Session.CmdType = FileTransferProtocol.CommandType.DownEnd;

            }
            //Session.FileBlock = session.Block;

            Session.FileBlock.CurrentSize = readCount;
            Session.FileBlock.Data = read;
            Session.FileBlock.HasTransfer = Session.FileBlock.HasTransfer + readCount;
            if (Session.FileBlock.TotalSize == Session.FileBlock.HasTransfer)
            {
                Session.FileBlock.Complated = true;
            }
            byte[] send = ObjectHelper.SerialzieObject<NetSession>(Session);
            Connection.BeginSend(send);
            if (Session.FileBlock.Complated)
            {
                Console.WriteLine(Session.FileBlock.BlockId + " : " + readCount.ToString());

                fs.Close();
               // Connection.BeginDisconnect();
            }
           // TimeSpan tt = DateTime.Now - dt;
          //  Console.WriteLine("Read and Send time:" + tt.TotalMilliseconds.ToString());
            TimeSpan ts = DateTime.Now - sendDt;
            sendDt = DateTime.Now;
            Console.WriteLine("Send time:" + ts.TotalMilliseconds.ToString());
        }
        
        private void ThreadReadAndSend(object session)
        {
            ThreadSession ts = session as ThreadSession;
            NetSession Session = ts.Session;
            ConnectionEventArgs e = ts.Connection;
            FileStream fs = new FileStream(Session.FileBlock.FileName, FileMode.Open, FileAccess.Read);
            //int nCount = 0;

            byte[] read = new byte[ConstValue.SendSize];
            while (!Session.FileBlock.Complated  )
            {
               // if (!ConnectStatus.ContainsKey(e.Connection.ConnectionId))
                //    break;
                int readCount = 0;
                fs.Seek(Session.FileBlock.BeginPos + Session.FileBlock.HasTransfer, SeekOrigin.Begin);
                if (Session.FileBlock.TotalSize > Session.FileBlock.HasTransfer + ConstValue.SendSize)
                {
                    Session.CmdType = FileTransferProtocol.CommandType.DownTransfer;
                    readCount = fs.Read(read, 0, ConstValue.SendSize);
                }
                else
                {
                    readCount = fs.Read(read, 0, (int)(Session.FileBlock.EndPos - Session.FileBlock.BeginPos - Session.FileBlock.HasTransfer) + 1);
                    Session.FileBlock.Complated = true;
                    Session.CmdType = FileTransferProtocol.CommandType.DownEnd;

                }
                //Session.FileBlock = session.Block;

                Session.FileBlock.CurrentSize = readCount;
                Session.FileBlock.Data = read;
                Session.FileBlock.HasTransfer = Session.FileBlock.HasTransfer + readCount;
                if (Session.FileBlock.TotalSize == Session.FileBlock.HasTransfer)
                {
                    Session.FileBlock.Complated = true;
                }
                byte[] send = ObjectHelper.SerialzieObject<NetSession>(Session);
               // if (ConnectStatus.ContainsKey(e.Connection.ConnectionId))
                    e.Connection.BeginSend(send);
                if (Session.FileBlock.Complated)
                    Console.WriteLine(Session.FileBlock.BlockId + " : " + readCount.ToString());
                //  Event(Session.FileBlock);

                // Console.WriteLine(send.Length.ToString());
                //if (RecSyncs.Keys.Contains(e.Connection.ConnectionId))
                //{
                //    RecSyncs[e.Connection.ConnectionId].ReceiveCount++;
                //    while (RecSyncs.Keys.Contains(e.Connection.ConnectionId) && RecSyncs[e.Connection.ConnectionId].ReceiveCount > 2)
                //    {
                //        Thread.Sleep(50);
                //    }

                //}
            }
            fs.Close();
        }
        #region OnConnected

        public override void OnConnected(ConnectionEventArgs e)
        {

            StringBuilder s = new StringBuilder();

            s.Append("\r\n------------------------------------------------\r\n");
            s.Append("New Client\r\n");
            s.Append(" Connection Id " + e.Connection.ConnectionId + "\r\n");
            s.Append(" Ip Address " + e.Connection.RemoteEndPoint.Address + "\r\n");
            s.Append(" Tcp Port " + e.Connection.RemoteEndPoint.Port + "\r\n");
            //ConnectStatus.Add(e.Connection.ConnectionId, true);
            Event(s.ToString());
            s.Length = 0;
            //RecSyncs.Add(e.Connection.ConnectionId, new ReceiveSync());
            e.Connection.UserData = new NetSession(ConnectionState.Connected);
            e.Connection.BeginReceive();

        }
        
        #endregion

        #region OnSent

        public override void OnSent(MessageEventArgs e)
        {

            //if (!e.SentByServer)
            //{
            //    e.Connection.BeginReceive();
            //}
            if(DownLoadSessions.ContainsKey(e.Connection.ConnectionId))
            {
                NetSession session = DownLoadSessions[e.Connection.ConnectionId];
                ReadAndSend(e.Connection, session);
            }
           // Console.WriteLine(e.Connection.ConnectionId.ToString());
        }

        #endregion

        #region OnReceived
        private DateTime recdt = DateTime.Now;
        public override void OnReceived(MessageEventArgs e)
        {
            if (e.Buffer == null)
            {
                e.Connection.BeginReceive();
                return;
            }

            NetSession msg = null;
            byte[] sendBuffer = null;
            try
            {
                msg = ObjectHelper.DeserialzieObject<NetSession>(e.Buffer);
            }
            catch (Exception ex)
            {
                Fcdbas.Core.Log.XTrace.WriteException(ex, MainForm.LogPath);
                Console.WriteLine(ex.Message);
            }
            switch (msg.CmdType)
            {

                case CommandType.UpInit:

                    ((NetSession)e.Connection.UserData).State = ConnectionState.Authenticated;
                    msg.State = ConnectionState.Authenticated;
                    bool resume = false;
                    msg.CmdType = CommandType.UpBegin;
                    msg.Head = InitTransferHead(msg.Head,ref resume);
                    if (resume)
                        msg.CmdType = CommandType.UpResume;
                    e.Connection.BeginSend(ObjectHelper.SerialzieObject<NetSession>(msg));

                    break;

                case CommandType.UpTransfer:
                    TimeSpan ts = DateTime.Now - recdt;
                    recdt = DateTime.Now;
                    Console.WriteLine("rec time :" + ts.TotalMilliseconds.ToString());
                    WriteToTempFile(msg.FileBlock);
                    FileBlock fb = new FileBlock();
                    fb.BlockId = msg.FileBlock.BlockId;
                    fb.HasTransfer = msg.FileBlock.HasTransfer;
                    msg.FileBlock = fb;
                    msg.CmdType = CommandType.UpSucess;
                    byte[] f = ObjectHelper.SerialzieObject<NetSession>(msg);
                    e.Connection.BeginSend(f);
                   
                    break;
                case CommandType.UpReady:
                    e.Connection.BeginSend(e.Buffer);
                    break;

                case CommandType.UpEnd:
                    WriteToFile(msg.FileBlock);
                    FileBlock fb1 = new FileBlock();
                    fb1.BlockId = msg.FileBlock.BlockId;
                    fb1.HasTransfer = msg.FileBlock.HasTransfer;
                    fb1.Complated = msg.FileBlock.Complated;
                    msg.FileBlock = fb1;
                    sendBuffer = ObjectHelper.SerialzieObject<NetSession>(msg);
                    e.Connection.BeginSend(sendBuffer);
                    break;
                case CommandType.FetchList:
                   // List<TFileInfo> fileList = new List<TFileInfo>();
                   // FindFile(fileList, this.DownLoadPath);
                    lock (LockDLList)
                    {
                        msg.Content = DownLoadList.ToXml();
                    }
                    sendBuffer = ObjectHelper.SerialzieObject<NetSession>(msg);
                    e.Connection.BeginSend(sendBuffer);
                    break;
                case CommandType.FetchDownFileInfo:
                    
                    msg.Head = TransferHead.CreateTransferHead(msg.Content);
                    msg.CmdType = CommandType.DownInit;
                    sendBuffer = ObjectHelper.SerialzieObject<NetSession>(msg);
                    e.Connection.BeginSend(sendBuffer);
                    break;
                case CommandType.DownReady:
                    e.Connection.BeginSend(e.Buffer);
                    break;
                case CommandType.DownBegin:
                    //ThreadSession ses = new ThreadSession();
                   // ses.Connection = e;
                   // ses.Session = msg;
                   // Thread read = new Thread(new ParameterizedThreadStart(ThreadReadAndSend));
                    //read.Start(ses);
                    if (!DownLoadSessions.ContainsKey(e.Connection.ConnectionId))
                        DownLoadSessions.Add(e.Connection.ConnectionId, msg);
                    else
                        DownLoadSessions[e.Connection.ConnectionId] = msg;
                    ReadAndSend(e.Connection, msg);
                    break;
                case CommandType.DownSucess:
                    //if (RecSyncs.Keys.Contains(e.Connection.ConnectionId))
                    //    RecSyncs[e.Connection.ConnectionId].ReceiveCount--;
                    break;
            }

            e.Connection.BeginReceive();

        }
        
        
        #endregion

        #region OnDisconnected

        public override void OnDisconnected(ConnectionEventArgs e)
        {

            StringBuilder s = new StringBuilder();

            s.Append("------------------------------------------------" + "\r\n");
            s.Append("Client Disconnected\r\n");
            s.Append(" Connection Id " + e.Connection.ConnectionId + "\r\n");

            e.Connection.UserData = null;
            //if (ConnectStatus.ContainsKey(e.Connection.ConnectionId))
            //{
            //    ConnectStatus.Remove(e.Connection.ConnectionId);
            //}
            Event(s.ToString());
            if (DownLoadSessions.ContainsKey(e.Connection.ConnectionId))
                DownLoadSessions.Remove(e.Connection.ConnectionId);
            //if (RecSyncs.Keys.Contains(e.Connection.ConnectionId))
            //    RecSyncs.Remove(e.Connection.ConnectionId);
            s.Length = 0;


        }

        #endregion

        #region OnException

        public override void OnException(ExceptionEventArgs e)
        {
            StringBuilder s = new StringBuilder();

            s.Append("------------------------------------------------" + "\r\n");
            s.Append("Exception - " + e.Exception.GetType().ToString() + "\r\n");
            s.Append("Exception Message - " + e.Exception.Message + "\r\n");

            if (e.Exception is ReconnectAttemptException)
            {
                s.Append("Attempted   - " + ((ReconnectAttemptException)e.Exception).Attempt.ToString() + "\r\n");
                s.Append("Max Reached - " + ((ReconnectAttemptException)e.Exception).MaxReached.ToString() + "\r\n");
                s.Append("------------------------------------------------" + "\r\n");
                //s.Append("Inner Error - " + ((SocketException)e.Exception.InnerException).ErrorCode.ToString() + "\r\n");
                s.Append("------------------------------------------------" + "\r\n");
                // s.Append("Creator - " + ((ReconnectAttemptException)e.Exception).Creator.Name + "\r\n");
                // s.Append("Creator - " + ((ReconnectAttemptException)e.Exception).Creator.EncryptType.ToString() + "\r\n");
                // s.Append("Creator - " + ((ReconnectAttemptException)e.Exception).Creator.CompressionType.ToString() + "\r\n");

            }

            if (e.Exception is SocketException)
            {
                s.Append("Socket Error - " + ((SocketException)e.Exception).ErrorCode.ToString() + "\r\n");
            }

            s.Append("------------------------------------------------" + "\r\n");

            Fcdbas.Core.Log.XTrace.Write(s.ToString(), MainForm.LogPath);
            e.Connection.BeginDisconnect();

        }

        #endregion
    }
    public class ConfigSrv
    {
        public string SavePath
        {
            get;
            set;
        }
        public int Port
        {
            get;
            set;
        }
        public string DownLoadPath
        {
            get;
            set;
        }
        public bool IsEnableRaising
        {
            get;
            set;
        }
        public string IP
        {
            get;
            set;
        }
    }
}
